/*
 * 文件名： WechatWcPayCmbcServiceImpl.java
 * 
 * 工程名称: bis-service
 *
 * Gopay
 *
 * 创建日期： 2017年5月15日
 *
 * Copyright(C) 2017, by www.gopay.com.cn Inc.All rights reserved.
 *
 * 原始作者: 宣广海
 *
 */
package com.gopay.bis.service.bank.impl.wcpay;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.manager.bank.wcpay.WcpayCmbcManager;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.wechat.wcpay.citic.res.WcPayNotifyMsg;
import com.gopay.common.domain.bank.wechat.wcpay.citic.res.WcPayResMsg;
import com.gopay.common.domain.bank.wechat.wcpay.cmbc.NotifyMsgBody;
import com.gopay.common.domain.bank.wechat.wcpay.cmbc.PayMsgBody;
import com.gopay.common.domain.bank.wechat.wcpay.cmbc.QueryMsgBody;
import com.gopay.common.domain.bank.wechat.wcpay.cmbc.RefundMsgBody;
import com.gopay.common.domain.bank.wechat.wcpay.cmbc.TransMsg;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.WcPayInteractRemoteService;

/**
 * 微信公众号支付民生银行渠道业务处理
 *
 * @author 宣广海
 *
 * @version
 *
 * @since 2017年5月15日
 */
public class WcPayCmbcServiceImpl implements WcPayInteractRemoteService {

	private static Logger logger = LoggerFactory.getLogger(WcPayCmbcServiceImpl.class);

	@Resource(name = "wcpayCmbcManager")
	private WcpayCmbcManager wcpayCmbcManager;

	@Override
	public Result pay(BaseMessage msg) throws GopayException {
		Result result = new Result(false);
		try {
			@SuppressWarnings("unchecked")
			TransMsg<PayMsgBody> resMessage = (TransMsg<PayMsgBody>) wcpayCmbcManager.payment(msg);
			logger.info("---微信公众号/支付宝服务窗支付民生渠道返回处理对象：" + ToStringBuilder.reflectionToString(resMessage));
			WcPayResMsg respMsg = new WcPayResMsg();
			PayMsgBody payMsgBody = (PayMsgBody) resMessage.getMsgBody();

			if (StringUtils.equalsIgnoreCase("R", resMessage.getMsgHead().getRespType())
					&& (StringUtils.isNotBlank(payMsgBody.getWxjsapiStr())
							|| StringUtils.isNotBlank(payMsgBody.getChannelNo()))) {
				BeanUtils.copyProperties(resMessage, respMsg);
				String payInfo = null;
				if (StringUtils.isNotBlank(payMsgBody.getWxjsapiStr())
						&& msg.getOutStlmCd().equals(BankConstants.BANK_LOGO_WECHAT)) {
					payInfo = payMsgBody.getWxjsapiStr();
				}
				if (StringUtils.isNotBlank(payMsgBody.getChannelNo())
						&& msg.getOutStlmCd().equals(BankConstants.BANK_LOGO_ALIPAY)) {
					payInfo = payMsgBody.getChannelNo();
				}
				respMsg.setPayInfo(payInfo);
				result.setDefaultModel(respMsg);
				result.setSuccess(true);
			} else {
				result.setResultCode(ProcCodeConstants.PROC_CODE_100E1159);
				result.setErrorMsg(resMessage.getMsgHead().getRespMsg());
				result.setSuccess(false);
			}
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7025);
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Result orderQuery(BaseMessage msg) throws GopayException {
		Result result = new Result();
		try {
			TransMsg<QueryMsgBody> resMsg = (TransMsg<QueryMsgBody>) wcpayCmbcManager.orderQuery(msg);
			logger.info("---微信公众号/支付宝服务窗支付民生渠道订单查询返回处理对象：" + ToStringBuilder.reflectionToString(resMsg));
			if (null == resMsg.getMsgBody().getTotalAmount()) {
				resMsg.setAmount(msg.getAmount());
			} else {
				resMsg.setAmount(resMsg.getMsgBody().getTotalAmount());
			}
			result.setDefaultModel(resMsg);
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		}
		return result;

	}

	@Override
	public Result refund(BaseMessage msg) throws GopayException {
		Result result = new Result(false);
		try {
			@SuppressWarnings("unchecked")
			TransMsg<RefundMsgBody> resMsg = (TransMsg<RefundMsgBody>) wcpayCmbcManager.refund(msg);
			if (resMsg != null) {
				if (!"E".equals(resMsg.getMsgHead().getRespType())) {
					result.setDefaultModel(resMsg);
					result.setSuccess(true);
					// 接收成功
					result.setModel("falg", true);
				} else {
					result.setSuccess(false);
					result.setModel("falg", false);
					result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
					result.setErrorMsg(resMsg.getMsgHead().getRespMsg());
				}
			} else {
				result.setSuccess(false);
				result.setModel("falg", false);
				result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
			}

		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
		}
		return result;
	}

	@Override
	public Result refundQuery(BaseMessage msg) throws GopayException {
		Result result = new Result();
		try {
			@SuppressWarnings({ "unchecked" })
			TransMsg<QueryMsgBody> resMsg = (TransMsg<QueryMsgBody>) wcpayCmbcManager.orderQuery(msg);
			logger.info("---微信公众号/支付宝服务窗支付民生渠道退款订单查询返回处理对象：" + ToStringBuilder.reflectionToString(resMsg));
			if (null == resMsg.getMsgBody().getTotalAmount()) {
				resMsg.setAmount(msg.getAmount());
			} else {
				resMsg.setAmount(resMsg.getMsgBody().getTotalAmount());
			}
			result.setDefaultModel(resMsg);
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
		}
		return result;

	}

	@Override
	public Result verify(BaseMessage msg) throws GopayException {
		Result result = new Result(false);
		try {
			//TransMsg<NotifyMsgBody> verifyMsg = (TransMsg<NotifyMsgBody>) msg;			
			TransMsg<NotifyMsgBody> verifyMsg = new TransMsg<NotifyMsgBody>();
			WcPayNotifyMsg message = (WcPayNotifyMsg) msg;
			BeanUtils.copyProperties(msg, verifyMsg);
			
			Boolean flag = (Boolean) wcpayCmbcManager.verify(verifyMsg);
			result.setDefaultModel(flag);
			result.setSuccess(true);
			result.setModel("res", message);
			Map<String, String> param = new HashMap<String, String>(9);
			/**
			 * 验签成功
			 */
			if ((boolean) result.getDefaultModel()) {
				if (("0".equals(message.getPay_result()))) {
					param.put("orderId", verifyMsg.getOrderId());
					param.put("amt", String.valueOf(verifyMsg.getAmount()));
					param.put("cardType", "Unknown");
					param.put("notifyNum", "1");
					param.put("payStatus", "00");
					param.put("retCode", "00");
					param.put("retMsg", "验签成功");
					param.put("signData", "");
					param.put("isFront", String.valueOf(verifyMsg.isFront()));
					result.setModel("isNotifyCashier", param);
					result.setOrderStatus(true);
				}
				} else {
					param.put("orderId", verifyMsg.getOrderId());
					param.put("amt", String.valueOf(verifyMsg.getAmount()));
					param.put("cardType", "Unknown");
					param.put("notifyNum", "1");
					param.put("payStatus", "01");
					param.put("retCode", "01");
					param.put("retMsg", "验签失败");
					param.put("signData", "");
					param.put("isFront", String.valueOf(verifyMsg.isFront()));
					result.setModel("isNotifyCashier", param);
					result.setOrderStatus(false);
				}

		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6064);
		}
		return result;

	}

}
